
import { _decorator, Component, Node, Input, input, EventKeyboard, KeyCode, Vec3, math, RigidBody, Collider, ITriggerEvent, BoxCollider } from 'cc';
import { GameMgr } from './GameMgr';
import { MapMaker } from './MapMaker';
const { ccclass, property } = _decorator;

/**
 * Predefined variables
 * Name = PlayerControllers
 * DateTime = Sun Mar 06 2022 14:10:25 GMT+0800 (中国标准时间)
 * Author = lamd
 * FileBasename = PlayerControllers.ts
 * FileBasenameNoExtension = PlayerControllers
 * URL = db://assets/Scripts/PlayerControllers.ts
 * ManualUrl = https://docs.cocos.com/creator/3.4/manual/en/
 *
 */

@ccclass('PlayerControllers')
export class PlayerControllers extends Component {
    // [1]
    // dummy = '';

    // [2]
    // @property
    // serializableDummy = 0;
    worldY: number = 0;
    x: number = 0;
    z: number = 0;
    map: MapMaker = null!;
    playerOver: boolean = false;
    rigidbodyCom: RigidBody = null!;
    colliderCom: BoxCollider = null!;

    onLoad() {
        this.worldY = this.node.worldPosition.y;
        this.colliderCom = this.node.getComponent(BoxCollider)
    }

    start() {
        input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this);

        this.colliderCom.on('onTriggerEnter', this.onTrigger, this);
        // this.colliderCom.on('onCollisionEnter', this.onTrigger, this);
    }

    init() {
        this.map = GameMgr.instance.map;

        // 初始位置 x=2, z = 5
        this.x = 2;
        this.z = 5;

        this.corretPosSelf();
        this.playerOver = false;

        if (this.rigidbodyCom)
            this.rigidbodyCom.enabled = false
    }

    dropPlayer() {
        if (!this.playerOver) {
            this.playerOver = true;

            this.rigidbodyCom = this.node.getComponent(RigidBody)
            if (this.rigidbodyCom == null)
                this.rigidbodyCom = this.node.addComponent(RigidBody)

            this.rigidbodyCom.enabled = true
        }
    }

    corretPosSelf() {
        this.corretPos(this.x, this.z)

        GameMgr.instance.checkGameOverWithDrop();

        // 地图不足时，创建地图
        let mapData: Node[][] = this.map.getTileNode();
        let mapLen: number = mapData.length
        if (mapLen - this.z < 22) {
            let offsetz: number = mapData[mapLen - 1][0].worldPosition.z - mapData[0][0].worldPosition.z - this.map.tileOffset / 2
            this.map.createChunk(offsetz);
        }
    }

    corretPos(column: number, row: number) {
        console.log("modify column, row ", column, row);

        let nodes: Node[][] = this.map.getTileNode();
        let nodePos: Vec3 = nodes[row][column]?.worldPosition;
        nodePos.y = this.worldY;
        this.node.worldPosition = nodePos;
    }

    private onTrigger(event: ITriggerEvent) {
        console.log(event.type, event);
        // 碰到的是地板
        if (event.otherCollider.node.name == "normal_a2" || event.selfCollider.node.name == "normal_a2") return true;


        if (GameMgr.instance.isGameOver) 
            return true;

        // event.otherCollider.isTrigger = false;
        GameMgr.instance.gameOver();
        return true;
    }

    // 左移
    left() {
        if (GameMgr.instance.isGameOver) return;

        let isLongRow: boolean = this.map.isLongRow(this.z);
        if (this.x > 0) {
            this.map.trail(this.x, this.z);
            this.z++;

            if (isLongRow)
                this.x--;
            this.corretPosSelf();
        }
    }

    // 右移
    right() {
        if (GameMgr.instance.isGameOver) return;

        let isLongRow: boolean = this.map.isLongRow(this.z);
        if (this.x < 4 || (isLongRow && this.x < 5)) {
            this.map.trail(this.x, this.z);
            this.z++;

            if (!isLongRow)
                this.x++

            this.corretPosSelf();
        }
    }

    onKeyDown(event: EventKeyboard) {
        if (event.keyCode == KeyCode.KEY_M)
            this.right();
        if (event.keyCode == KeyCode.KEY_N)
            this.left();

    }
}

/**
 * [1] Class member could be defined like this.
 * [2] Use `property` decorator if your want the member to be serializable.
 * [3] Your initialization goes here.
 * [4] Your update function goes here.
 *
 * Learn more about scripting: https://docs.cocos.com/creator/3.4/manual/en/scripting/
 * Learn more about CCClass: https://docs.cocos.com/creator/3.4/manual/en/scripting/decorator.html
 * Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.4/manual/en/scripting/life-cycle-callbacks.html
 */
